/**
 * Progetto PRAISED.
 * 13/dic/2010
 */
package it.uniroma3.dia.praised.pubmed.parser;

import it.uniroma3.dia.praised.exception.CrawlerException;

import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.gargoylesoftware.htmlunit.ElementNotFoundException;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlDivision;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

/**
 * @author Accosta Augusto
 * @author Lopez Elisabetta
 *
 */
public class ParserPubMed {

	
	/**
	 * Costruttore no-arg
	 */
	public ParserPubMed() {
	}
	
	/**
	 * 
	 * @param page
	 * @param pattern
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String getPatternItem(HtmlPage page, String pattern) {
		
		try {
			List<HtmlDivision> nodes = (List<HtmlDivision>) page.getByXPath(pattern);
			String textContent = nodes.get(0).getTextContent();
			
			return textContent;
		} catch (Exception e) {
			return "";
		}
	}
	
	/**
	 * Pulisce il PMCID
	 * @param value
	 * @return
	 */
	public String retrievePMCID(String value) {
		return value.substring(value.lastIndexOf(" ") + 1);
	}
	
	/**
	 * Metodo che recupera i link degli articoli ottenuti dall'esecuzione della query
	 * 
	 * @param webPageResult
	 * @return la lista dei link
	 * @throws CrawlerException
	 */
	public Map<String, URL> getArticleLinks(HtmlPage page, String PMCID) throws CrawlerException {
		
		try {
			Map<String, URL> mapURL = new HashMap<String, URL>();
			
			List<HtmlAnchor> links = page.getAnchors(); // Recupero delle ancore 
							
			for (HtmlAnchor htmlAnchor : links) {
				String content = htmlAnchor.getTextContent();
				if(content.contains("PDF"))
					content = "pdf";
				
				/* Infine si aggiungono solo i link relativi a quell'articolo sulla base del PMCID */
				if(htmlAnchor.getHrefAttribute().contains("/" + PMCID + "/"))
					mapURL.put(content, new URL(htmlAnchor.getHrefAttribute()));
				}
    		
			return mapURL;
			
		} catch (FailingHttpStatusCodeException e) {
			throw new CrawlerException(e.getMessage());
		} catch (IOException e) {
			throw new CrawlerException(e.getMessage());
		}
	}

	/* **********************************************************************************
	 *	
	 *						SEZIONE METODI DI APPOGGIO UTILIZZATI
	 *
	 * *********************************************************************************/
	
	/**
	 * Recupera il numero di risultati per pagina del sistema NCBI leggendo gli hidden field embeddati nel codice HTML
	 * Ritorna 0 se l'elemento cercato non esiste, ossia la pagina contiene pochi risultati che � inutile processarla
	 * @param page
	 * @return
	 * @throws CrawlerException 
	 */
	public static int pageSize(HtmlPage page) throws CrawlerException {
		String result = "";
		try {
			
			HtmlInput input = page.getElementByName("EntrezSystem2.PEntrez.Pmc.Pmc_ResultsPanel.Pager.InitialPageSize");
			result = input.getAttribute("value");
			
		} catch (FailingHttpStatusCodeException e) {
			throw new CrawlerException(e.getMessage());
		} catch (ElementNotFoundException e) {
			return 0;
		}
		
		return Integer.parseInt(result);
	}
	
	/**
	 * Recupera il numero di pagine prodotte dal sistema NCBI leggendo gli hidden field embeddati nel codice HTML.
	 * Ritorna 1 se l'elemento cercato non esiste, oppure se la pagina contiene pochi risultati
	 * @param page
	 * @return
	 * @throws CrawlerException
	 */
	public static int numberOfResultPage(HtmlPage page) throws CrawlerException {
		String result = "";
		try {
			
			HtmlInput input = page.getElementByName("EntrezSystem2.PEntrez.Pmc.Pmc_ResultsPanel.Pager.MaxPage");
			result = input.getAttribute("value");
			
		} catch (FailingHttpStatusCodeException e) {
			throw new CrawlerException(e.getMessage());
		} catch (ElementNotFoundException e) {
			return 1;
		}
		
		return Integer.parseInt(result);
	}

	
	/**
	 * Recupera il numero di risultati forniti dal sistema NCBI a partire alla query data
	 * @return
	 * @throws CrawlerException 
	 */
	public static int findNumberOfResultItems(HtmlPage page) throws CrawlerException {
		
		String result = "";
		
		try {
			
			HtmlDivision divElement = (HtmlDivision) page.getElementById("PaginationNode");
			String items = divElement.getChildNodes().item(0).getTextContent();
			result = items.substring(items.lastIndexOf(" ") + 1);
			
		} catch (FailingHttpStatusCodeException e) {
			throw new CrawlerException(e.getMessage());
		}
		
		return Integer.parseInt(result);
	}
	
}
